from dataclasses import asdict
from typing import Union

from fastapi import Response, status
from wazuh.core.engine.models.base import ErrorResponse
from wazuh.core.engine.models.vulnerability import ScanRequest, ScanResponse, Type
from wazuh.core.exception import WazuhEngineError

from comms_api.core.vulnerability import request_vulnerability_scan
from comms_api.routers.exceptions import HTTPError
from comms_api.routers.utils import timeout


@timeout(10)
async def post_scan_request(scan_request: ScanRequest) -> Union[ScanResponse, Response, ErrorResponse]:
    """Send a vulnerability scan request to the engine.

    Parameters
    ----------
    scan_request : ScanRequest
        Vulnerability scan request.

    Raises
    ------
    HTTPError
        If there is any error when communicating with the engine.

    Returns
    -------
    ScanResponse | Response | ErrorResponse
        The scan request response, an HTTP OK empty response or an error response.
    """
    try:
        if scan_request.type == Type.FULL_SCAN:
            if None in asdict(scan_request).values():
                raise HTTPError(
                    message='Full scan requires all fields to be set',
                    status_code=status.HTTP_400_BAD_REQUEST,
                )

        response = await request_vulnerability_scan(scan_request)
        if response is None:
            return Response(status_code=status.HTTP_200_OK)
        elif isinstance(response, ErrorResponse):
            raise HTTPError(': '.join(response.error), response.code, response.code)

        return response
    except WazuhEngineError as exc:
        raise HTTPError(message=exc.message, code=exc.code, status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)
